import React, { useState, useEffect, useMemo } from 'react';
import moment from 'moment';
import _ from 'lodash';
import { GlobalRegistry } from '@inbiz/core';
import { TextWidget, getMessage } from '@inbiz/react';
import {
  Button,
  Form,
  Input,
  Modal,
  Row,
  Col,
  Radio,
  Tabs,
  DatePicker,
  message,
  ConfigProvider,
  Slider,
} from 'antd';
import ImageCrop from '../ImageCrop';
// @@ 路径优化
import {
  globalTheme,
  topmenuTheme,
  leftmenuTheme,
} from './theme';
import {
  getUserAvatarBytoken,
  editUser,
  getLoginAndPasswordStrategy,
  changeUserPassword,
  setUserConfig,
  userChooseTheme,
  getCustomThemeDetail,
} from '../../services';
import { getEditor, getOfficialPreview, useApp, setTheme } from '@inbiz/utils';
import { replaceTheme } from '../../utils'
import { getPageJson } from '@inbiz/render';
import {commonLang} from '@inbiz/utils'
import './index.less';

export interface EditModalProps {
  visible?: boolean;
  configList?: any[];
  themes: any[];
  viewType: string;
  getLangMessage: Function;
  langs: any;
  hooksByTheme: any;
  hooksByPersonConfig: any;
  value?: string;
  className?: string;
  userInfo?: object; // 用户信息
  onCancel?: () => any; // 取消
  onSubmit?: () => any; // 提交保存
  themeList: string;
  random?: number;
  onRandom?: (num: number) => void;

}

const re = /^(?!([a-zA-Z]+|\d+)$)[a-zA-Z\d]{6,20}$/;
const marks = {
  12: {
    style: {
      fontSize: '12px',
    },
    label: 12,
  },
  13: {
    style: {
      fontSize: '13px',
    },
    label: 13,
  },
  14: {
    style: {
      fontSize: '14px',
    },
    label: 14,
  },
  15: {
    style: {
      fontSize: '15px',
    },
    label: 15,
  },
  16: {
    style: {
      fontSize: '16px',
    },
    label: 16,
  },
};

const EditModal: React.FC<EditModalProps> = (props) => {
  const { visible, onCancel, onSubmit, configList, viewType, userInfo, random, onRandom, themes } = props;
  const appInfo = useApp();
  const [form] = Form.useForm();
  const [formPassword] = Form.useForm();
  const [showImageCrop, $setShowImageCrop] = useState<boolean>(false);
  const [passwordStrategy, $setPasswordStrategy] = useState<any>();
  const [currentTheme, $currentTheme] = props.hooksByTheme;
  const [personConfig, $personConfig] = props.hooksByPersonConfig;
  const [themeItem, $themeItem] = useState<any>(null);
  const [cacheData, $cacheData] = useState<any>({
    ...personConfig,
    currentTheme: currentTheme,
    themeItem: themeItem,
  });

  // 获取密码策略
  const getPasswordStrategy = async () => {
    const data = await getLoginAndPasswordStrategy();
    if (data && !data.nResult) {
      $setPasswordStrategy(data.result);
    }
  };

  // 初始化用户信息
  const onFill = () => {
    const birthday = _.get(userInfo, 'Birthday');
    form.setFieldsValue({
      realName: _.get(userInfo, 'Name'),
      email: _.get(userInfo, 'Email'),
      telephone: _.get(userInfo, 'Telephone'),
      mobile: _.get(userInfo, 'Mobile'),
      genderMale: _.get(userInfo, 'Gender'),
      birthday: birthday ? moment(birthday) : '',
    });
  };

  // 修改密码
  const updatePassword = async () => {
    const values = await formPassword.validateFields();
    if (_.get(passwordStrategy, 'complicated') && !re.test(values.newPassword)) {
      formPassword.setFields([
        {
          name: 'newPassword',
          value: values.newPassword,
          errors: [getMessage('personalInfo.newPasswordTips')],
        },
      ]);
      return false;
    }
    try {
      const data = await changeUserPassword(values);
      if (data && data.result === 0) {
        message.success(getMessage('personalInfo.relogin'));
        setTimeout(() => {
          onSubmit && onSubmit();
        }, 3000);
      } else {
        if (data && data.result == 209) {
          formPassword.setFields([
            {
              name: 'oldPassword',
              value: values.oldPassword,
              errors: [getMessage('personalInfo.wrongOldPassword')],
            },
          ]);
          return false;
        }
        if (data && data.result == 207) {
          formPassword.setFields([
            {
              name: 'newPassword',
              value: values.newPassword,
              errors: [getMessage('personalInfo.wrongPasswordFormat')],
            },
          ]);
          return false;
        }
        message.error(getMessage('personalInfo.editFailed'));
      }
    } catch (e) {
      message.error(getMessage('personalInfo.editFailed'));
    }
  };

  // 修改用户信息提交
  const submitInfo = async () => {
    const values = await form.validateFields();
    values.birthday = values.birthday ? moment(values.birthday).format('YYYY-MM-DD') : '';
    try {
      const data = await editUser(values);
      if (data && data.result === 0) {
        message.success(getMessage('personalInfo.editSuccess'));
        onSubmit && onSubmit();
      } else if (data && data.result === 221) {
        message.error(getMessage('personalInfo.mailbeenUsed'));
      } if (data && data.result === 225) {
        message.error(getMessage('personalInfo.numberbeenUsed'));
      } else {
        if (data?.message) {
          message.error(data?.message);
        }
      }
    } catch (e) {
      message.error(getMessage('personalInfo.editFailed'));
    }
  };

  const [locale, $locale] = useState(commonLang[GlobalRegistry.getDesignerLanguage()?.toLocaleLowerCase() as keyof typeof commonLang])
  useEffect(() => {
    $locale(commonLang[GlobalRegistry.getDesignerLanguage()?.toLocaleLowerCase() as keyof typeof commonLang])
  }, [GlobalRegistry.getDesignerLanguage()]);

  const renderInfoView = () => {
    // 获取用户头像
    const ImgHead = getUserAvatarBytoken(_.get(userInfo, 'IdentityId'));
    // 判断用户信息是否可修改
    const enableEditUserInfo = _.get(passwordStrategy, 'enableEditUserInfo');

    onFill();
    return (
      <ConfigProvider locale={locale}>
        <div className="m-infoview">
          <Row>
            <Col span={4} offset={1}>
              <div
                className="imgview"
                onClick={() => {
                  if (enableEditUserInfo) {
                    $setShowImageCrop(true);
                  } else {
                    message.warning(getMessage('personalInfo.userInfoNotEdit'));
                  }
                }}
              >
                <img src={`${ImgHead}&r=${random}`} />
                <div className="updateTop">
                  <TextWidget>personalInfo.editAvatar</TextWidget>
                </div>
              </div>
            </Col>
            <Col span={14} offset={1}>
              <Form form={form} colon={false} autoComplete="off" labelWrap labelCol={{ span: 8 }}>
                <Form.Item
                  name="realName"
                  label={getMessage('personalInfo.name')}
                  rules={[
                    { required: true, message: getMessage('personalInfo.nameNotNull') },
                    {
                      pattern: /^.{1,50}$/,
                      message: getMessage('personalInfo.nameLengthErr'),
                    },
                  ]}
                >
                  <Input style={{ width: 220 }} maxLength={51} disabled={!enableEditUserInfo} />
                </Form.Item>
                <Form.Item
                  name="email"
                  label={getMessage('personalInfo.e_mail')}
                  rules={[
                    {
                      pattern: /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/,
                      message: getMessage('personalInfo.wroneEmailformat'),
                    },
                  ]}
                >
                  <Input style={{ width: 220 }} disabled={!enableEditUserInfo} />
                </Form.Item>
                <Form.Item
                  name="telephone"
                  label={getMessage('personalInfo.phone')}
                  rules={[
                    {
                      pattern: /^[0-9\-]+$/,
                      message: getMessage('personalInfo.wrongPhoneNumber'),
                    },
                  ]}
                >
                  <Input style={{ width: 220 }} disabled={!enableEditUserInfo} />
                </Form.Item>
                <Form.Item
                  name="mobile"
                  label={getMessage('personalInfo.cellPhone')}
                  rules={[
                    {
                      pattern: new RegExp(/^[1][3-9][\d]{9}/, 'g'),
                      message: getMessage('personalInfo.wrongCellphoneNumber'),
                    },
                  ]}
                >
                  <Input maxLength={11} style={{ width: 220 }} disabled={!enableEditUserInfo} />
                </Form.Item>
                {/* <Form.Item name="lang" label={getMessage('personalInfo.lang')} labelCol={{ span: 6 }}>
                <Select>
                  {langs.map((item) => {
                    return <Option key={item.Code}>{item.Name}</Option>;
                  })}
                </Select>
              </Form.Item> */}
                <Form.Item name="genderMale" label={getMessage('personalInfo.gender')}>
                  <Radio.Group disabled={!enableEditUserInfo}>
                    <Radio value={1}>
                      <TextWidget>personalInfo.male</TextWidget>
                    </Radio>
                    <Radio value={2}>
                      <TextWidget>personalInfo.female</TextWidget>
                    </Radio>
                  </Radio.Group>
                </Form.Item>
                <Form.Item name="birthday" label={getMessage('personalInfo.birthday')}>
                  <DatePicker style={{ width: 220 }} disabled={!enableEditUserInfo} />
                </Form.Item>
              </Form>
            </Col>
          </Row>
          <Row style={{ justifyContent: 'flex-end' }}>
            <Button onClick={onCancel} style={{ marginRight: 10 }}>
              <TextWidget>global.cancel</TextWidget>
            </Button>
            <Button type="primary" disabled={!enableEditUserInfo} onClick={() => submitInfo()}>
              <TextWidget>global.sure</TextWidget>
            </Button>
          </Row>
          {showImageCrop ? (
            <ImageCrop
              visible={showImageCrop}
              imgSource={ImgHead}
              onSubmit={() => {
                // onSubmit && onSubmit();
                onRandom && onRandom(Date.now());
                $setShowImageCrop(false);
              }}
              onCancel={() => $setShowImageCrop(false)}
            />
          ) : null}
        </div>
      </ConfigProvider>
    );
  };

  const renderPassWordView = () => {
    // 判断密码是否可修改
    const enableEditPwd = _.get(passwordStrategy, 'enableEditPwd');
    formPassword.resetFields()
    return (
      <Form
        form={formPassword}
        autoComplete="off"
        colon={false}
        className="m-infoview"
        labelWrap
        labelCol={{ span: 11 }}
      >
        <Row>
          <Col span={14} offset={3}>
            <Form.Item
              name="oldPassword"
              rules={[{ required: true, message: getMessage('personalInfo.oldPasswordEmpty') }]}
              label={getMessage('personalInfo.oldPassword')}
              labelCol={{ span: 11 }}
            >
              <Input.Password disabled={!enableEditPwd} />
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={14} offset={3}>
            <Form.Item
              name="newPassword"
              label={getMessage('personalInfo.newPassword')}
              rules={[
                { required: true, message: getMessage('personalInfo.imputNewPassword') },
                ({ getFieldValue }) => ({
                  validator(_, value) {
                    const confirmPassWord = getFieldValue('confirmPassWord');
                    if (value && value.length < passwordStrategy.length) {
                      return Promise.reject(
                        new Error(
                          `${getMessage('personalInfo.atLeast')}${passwordStrategy.length}${getMessage(
                            'personalInfo.digit',
                          )}`,
                        ),
                      );
                    }

                    if (confirmPassWord && confirmPassWord == value) {
                      formPassword.setFields([
                        { name: 'confirmPassWord', value: confirmPassWord, errors: undefined },
                      ]);
                    }

                    return Promise.resolve();
                  },
                }),
              ]}
              labelCol={{ span: 11 }}
            >
              <Input.Password disabled={!enableEditPwd} />
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={14} offset={3}>
            <Form.Item
              name="confirmPassWord"
              label={getMessage('personalInfo.confirmPassword')}
              required
              rules={[
                ({ getFieldValue }) => ({
                  validator(_, value) {
                    const newPassword = getFieldValue('newPassword');
                    console.log('value', value)
                    if (!value) {
                      return Promise.reject(new Error(getMessage('personalInfo.confirmPasswordEmpty')))
                    } else if (newPassword === value) {
                      formPassword.setFieldsValue({ newPassword });
                      return Promise.resolve();
                    }
                    return Promise.reject(new Error(getMessage('personalInfo.notSamePassword')));
                  },
                }),
              ]}
              labelCol={{ span: 11 }}
            >
              <Input.Password disabled={!enableEditPwd} />
            </Form.Item>
          </Col>
        </Row>
        <Row style={{ justifyContent: 'flex-end' }}>
          <Button onClick={onCancel} style={{ marginRight: 10 }}>
            <TextWidget>global.cancel</TextWidget>
          </Button>
          <Button type="primary" disabled={!enableEditPwd} onClick={() => updatePassword()}>
            <TextWidget>global.sure</TextWidget>
          </Button>
        </Row>
      </Form>
    );
  };

  // 主题
  const onChangeTheme = async () => {
    const opt = {
      theme: themeItem?.OutId || themeItem?.id,
      siteOutId: appInfo?.SiteInfo?.OutId,
    };
    const data = await userChooseTheme(opt);
    if (!data) return;
    setThemeConfig(themeItem, personConfig);
  };

  const setThemeConfig = async (theme: any, config?: any) => {
    let themeData = null;
    // 自定义主题
    if (theme.OutId) {
      const opt = {
        outId: theme.OutId,
        appId: appInfo?.AppId,
        dataVersionId: appInfo?.SiteInfo?.DataVersionId,
      };
      // 正式环境
      if (getOfficialPreview()) {
        const url = theme.ThemePath?.replaceAll('{AppId}', appInfo?.AppId);
        themeData = await getPageJson({}, url);
      } else {
        themeData = await getCustomThemeDetail(opt);
      }
    } else {
      themeData = {
        global: globalTheme(theme.langkey),
        topmenu: topmenuTheme(theme.langkey),
        leftmenu: leftmenuTheme(theme.langkey),
      };
    }
    const personTheme = replaceTheme(themeData, config ? config?.fontSize : personConfig?.fontSize);
    setTheme(personTheme, ConfigProvider);
  };

  // 渲染主题
  const renderThemeView = (themeList: any) => {
    const showThemeList = themes.filter((theme) =>
      themeList.some((themeKey: string) => {
        const weId = theme.id || theme.OutId;
        return weId == themeKey;
      }),
    );
    return (
      <div className="m-themeview">
        <div className="theme-color">
          {showThemeList.length > 0 ? (
            <>
              <p style={{ marginBottom: '10px' }}><TextWidget>PersonalInfo.themeColor</TextWidget></p>
              <ul className="theme">
                {showThemeList.map((item: any) => {
                  const weId = item.id || item.OutId;
                  const weName = item.langkey ? `themeconfig.${item.langkey}` : item.Name;
                  const weColor = item.color || item.Color;
                  return (
                    <li
                      title={getMessage(weName)}
                      key={weId}
                      onClick={() => {
                        $currentTheme(weId);
                        $themeItem(item);
                      }}
                    >
                      <Button
                        type="dashed"
                        className={currentTheme == weId ? 'theme-item selected' : 'theme-item'}
                      >
                        <span className="item-color" style={{ backgroundColor: weColor }}></span>

                        <span className="item-text">
                          {' '}
                          <TextWidget>{`${weName}`}</TextWidget>
                        </span>
                      </Button>
                    </li>
                  );
                })}
              </ul>
            </>
          ) : null}
        </div>
        <div>
          <p style={{ margin: '10px 0' }}><TextWidget>PersonalInfo.fontSize</TextWidget></p>
          <Slider
            value={personConfig?.fontSize ? personConfig.fontSize : 14}
            marks={marks}
            min={12}
            max={16}
            onChange={(value) => {
              $personConfig({
                ...personConfig,
                fontSize: value,
              });
            }}
          />
        </div>
        <Row style={{ justifyContent: 'flex-end', paddingTop: '60px' }}>
          <Button
            style={{ marginRight: 10 }}
            onClick={() => {
              $personConfig({
                ...personConfig,
                fontSize: cacheData?.fontSize,
              });
              $currentTheme(getOfficialPreview() ? cacheData?.currentTheme : appInfo?.Theme || cacheData?.currentTheme);
              $themeItem(cacheData?.themeItem);
              setThemeConfig(cacheData?.themeItem, cacheData);
              onCancel();
            }}
          >
            <TextWidget>global.cancel</TextWidget>
          </Button>
          <Button
            type="primary"
            onClick={() => {
              setUserConfig({
                appId: appInfo.AppId,
                siteOutId: appInfo.SiteInfo.OutId,
                configValue: JSON.stringify(personConfig || {}),
              });

              const data = {
                ...cacheData,
                currentTheme,
                themeItem,
                ...personConfig,
              };
              $cacheData(data);
              onChangeTheme();
              onSubmit();
            }}
          >
            <TextWidget>global.sure</TextWidget>
          </Button>
        </Row>
      </div>
    );
  };

  const personSetterList = configList?.find((item) => item.tagName == 'setter');

  useEffect(() => {
    if (getEditor() || themes.length == 0) {
      return;
    }
    // 查找当前选中的皮肤数据
    const showThemeList = themes.find((Item: any) => {
      const isCurrent = Item.id == currentTheme || Item.OutId == currentTheme;
      return isCurrent;
    });

    if (showThemeList) {
      const theme = showThemeList;
      if (theme) {
        if (!cacheData.themeItem) cacheData.themeItem = theme;
        $themeItem(theme);
        setThemeConfig(theme, personConfig);
      }
    }
  }, [currentTheme]);

  useEffect(() => {
    if (visible) {
      getPasswordStrategy();
      onFill();

      const data = {
        ...cacheData,
        ...personConfig,
      };
      $cacheData(data);
    }
  }, [visible]);



  return (
    <Modal
      footer={null}
      title={getMessage('personalInfo.editInfo')}
      visible={visible}
      onOk={onSubmit}
      onCancel={onCancel}
      bodyStyle={{ padding: `0 20px 20px 20px` }}
      width={600}
    >
      <Tabs defaultActiveKey="person-key-1">
        {viewType != 'simple' ? (
          <>
            <Tabs.TabPane tab={getMessage('personalInfo.basicInfo')} key="person-key-1">
              {renderInfoView()}
            </Tabs.TabPane>
            <Tabs.TabPane tab={getMessage('personalInfo.setPassword')} key="person-key-2">
              {renderPassWordView()}
            </Tabs.TabPane>
          </>
        ) : (
          personSetterList.personConfig?.map((item: any, i: number) => {
            // 若被设置该项隐藏
            if (!item.status.value) {
              return;
            }
            return (
              <Tabs.TabPane tab={getMessage(item.name.value)} key={`person-key-${i + 1}`}>
                {item.id == 'theme'
                  ? renderThemeView(item?.theme?.value)
                  : item.id == 'basic'
                    ? renderInfoView()
                    : item.id == 'password'
                      ? renderPassWordView()
                      : null}
              </Tabs.TabPane>
            );
          })
        )}
      </Tabs>
    </Modal>
  );
};

export default EditModal;
